﻿using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine.Networking;
using UnityEngine.Events;
namespace Tools
{
    public class EzAssetManager : Singleton<EzAssetManager>
    {
        private static readonly object _syslock = new object();
        private Dictionary<string, GameObject> dicGameObject;//缓存
        private Dictionary<string, AssetBundle> dicAssetBundle;
        private Dictionary<string, Material> dicMaterial;
        private Dictionary<string, UnityEngine.Object> dicObject;
        private Dictionary<string, AssetBundleRequest> dicAssetBundleRequest;
        public EzAssetManager()
        {
            dicGameObject = new Dictionary<string, GameObject>();
            dicAssetBundle = new Dictionary<string, AssetBundle>();
            dicObject = new Dictionary<string, UnityEngine.Object>();
            dicMaterial = new Dictionary<string, Material>();
            dicAssetBundleRequest = new Dictionary<string, AssetBundleRequest>();
        }

        /// <summary>
        /// 从Resources中生成物体
        /// </summary>
        /// <param name="ResourcesPath"></param>
        /// <returns></returns>
        public GameObject CreateObjFromRes(string ResourcesPath)
        {
            string PerfabeName = GetResourcePath(ResourcesPath);
            return GameObject.Instantiate(dicGameObject[PerfabeName]);
        }

        public GameObject CreateObjFromRes(string ResourcesPath, Transform parent)
        {
            string PerfabeName = GetResourcePath(ResourcesPath);
            return UnityEngine.Object.Instantiate(dicGameObject[PerfabeName], parent);
        }

        public GameObject CreateObjFromRes(string ResourcesPath, Vector3 Posion, Quaternion rotation)
        {
            string PerfabeName = GetResourcePath(ResourcesPath);
            return UnityEngine.Object.Instantiate(dicGameObject[PerfabeName], Posion, rotation);
        }

        public GameObject CreateObjFromRes(string ResourcesPath, Vector3 position, Quaternion rotation, Transform parent)
        {
            string PerfabeName = GetResourcePath(ResourcesPath);
            return UnityEngine.Object.Instantiate(dicGameObject[PerfabeName], position, rotation, parent);
        }


        private string GetResourcePath(string ResourcesPath)
        {
            string[] names = ResourcesPath.Split('/');

            string PerfabeName;
            if (names.Length == 0)
            {
                PerfabeName = ResourcesPath;
            }
            else
            {
                PerfabeName = names[names.Length - 1];
            }
            if (dicGameObject.ContainsKey(PerfabeName))//如果对象池里有这个文件
            {
                Debug.Log("从对象池中加载预制体");
            }
            else
            {
                GameObject obj = Resources.Load<GameObject>(ResourcesPath);
                dicGameObject.Add(PerfabeName, obj);
            }
            return PerfabeName;
        }

        /// <summary>
        /// 加载AB包中的某个物体到场景中
        /// </summary>
        /// <param name="ULR">AB包地址</param>
        /// <param name="PerfabePath"></param>
        /// <returns></returns>
        IEnumerator CreatePerfabeFromeABAsyToScence<T>(string ULR, string PerfabePath)
        {
#if UNIYU_2018
         UnityWebRequest WebRequest = UnityWebRequestAssetBundle.GetAssetBundle(ULR);
#else
            UnityWebRequest WebRequest = UnityWebRequestAssetBundle.GetAssetBundle(ULR);
#endif
            yield return WebRequest.SendWebRequest();
            AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(WebRequest);
            var loadAsset = bundle.LoadAssetAsync<T>(PerfabePath);
            yield return loadAsset;
            GameObject obj = loadAsset.asset as GameObject;
        }

        IEnumerator CreatePerfabeFromeABAsyToScence(string ULR, string PerfabePath, UnityAction<GameObject> action)
        {
#if UNIYU_2018
         UnityWebRequest WebRequest = UnityWebRequestAssetBundle.GetAssetBundle(ULR);
#else
            UnityWebRequest WebRequest = UnityWebRequestAssetBundle.GetAssetBundle(ULR);
#endif
            yield return WebRequest.SendWebRequest();
            AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(WebRequest);
            AssetBundleRequest loadAsset = bundle.LoadAssetAsync(PerfabePath);
            yield return loadAsset;
            GameObject tempObj = GameObject.Instantiate(loadAsset.asset as GameObject);
            action(tempObj);
        }

        /// <summary>
        /// 加载AB包异步
        /// </summary>
        /// <param name="ULR"></param>
        /// <param name="PerfabePath"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public IEnumerator LoadABFromAsy(string ULR, string PerfabePath, UnityAction<AssetBundleRequest> action)
        {
            if (dicAssetBundleRequest.ContainsKey(ULR + PerfabePath))
            {
                action(dicAssetBundleRequest[ULR + PerfabePath]);
            }
            else
            {
#if UNIYU_2018
         UnityWebRequest WebRequest = UnityWebRequestAssetBundle.GetAssetBundle(ULR);
#else
                UnityWebRequest WebRequest = UnityWebRequestAssetBundle.GetAssetBundle(ULR);
#endif
                yield return WebRequest.SendWebRequest();
                AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(WebRequest);
                AssetBundleRequest loadAsset = bundle.LoadAssetAsync<GameObject>(PerfabePath);
                action(loadAsset);
                dicAssetBundleRequest.Add(ULR + PerfabePath, loadAsset);
            }
        }


        //同步加载Resources资源
        public T Load<T>(string name) where T : UnityEngine.Object
        {
            T res = Resources.Load<T>(name);
            if (res is GameObject)
            {
                return GameObject.Instantiate(res);
            }
            else
            {
                return res;
            }
        }

        //异步加载资源  Resource
        public void LoadAsy<T>(string name, UnityEngine.Events.UnityAction<T> action) where T : UnityEngine.Object
        {
            EzMonoManager.Instance.StartCoroutine(ResLoadReallyLoadAsync(name, action));
        }

        ///同步加载资源
        public void LoadABObjAsy(string URL, string PrefabeName, UnityEngine.Events.UnityAction<AssetBundleRequest> action)
        {
            EzMonoManager.Instance.StartCoroutine(LoadABFromAsy(URL, PrefabeName, action));
        }

        private IEnumerator ResLoadReallyLoadAsync<T>(string name, UnityEngine.Events.UnityAction<T> action) where T : UnityEngine.Object
        {
            ResourceRequest res = Resources.LoadAsync(name);
            yield return res;
            if (res.asset is GameObject)
            {
                action(GameObject.Instantiate(res.asset) as T);
            }
            else
            {
                action(res.asset as T);
            }
        }

        /// <summary>
        ///同步加载AB包
        /// </summary>
        /// <param name="PerfabeName">AB包名</param>
        /// <param name="ABPath">AB包路径</param>
        /// <returns></returns>
        public T LoadABGameObject<T>(string ABPath, string PrefabeName) where T : UnityEngine.Object
        {
            AssetBundle assetBundle = AssetBundle.LoadFromFile(ABPath);
            T asset = assetBundle.LoadAsset<T>(PrefabeName);
            if (asset is GameObject)
            {
                return GameObject.Instantiate(asset);
            }
            return asset;
        }
    }

}

